package tms.util.logging;

import tms.util.context.ApplicationContext;
import tms.util.context.LoggingConfig;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.logging.*;

public class JulLoggerFactory extends LoggerFactoryBase {

    @Override
    void initLoggingFramework() {
    }

    @Override
    public Logger getLogger(AreaType area) {
        return new JulLoggerAdapter(area);
    }


    private class JulLoggerAdapter implements Logger {
        private java.util.logging.Logger logger;

        public JulLoggerAdapter(AreaType area) {
            logger = java.util.logging.Logger.getLogger(area.path());
            logger.setUseParentHandlers(true);
            logger.addHandler(buildHandler(area));
        }

        @Override
        public void info(String message) {
            logger.info(message);
        }

        @Override
        public void warning(String message) {
            logger.warning(message);
        }

        @Override
        public void warning(String message, Throwable cause) {
            logger.log(Level.WARNING, message, cause);
        }

        @Override
        public void info(String message, Object... params) {
            info(MessageFormat.format(message, params));
        }

        @Override
        public void warning(String message, Object... params) {
            warning(MessageFormat.format(message, params));
        }

        @Override
        public void warning(String message, Throwable cause, Object... params) {
            warning(MessageFormat.format(message, params), cause);
        }

        @Override
        public void error(String message, Throwable cause) {
            logger.log(Level.SEVERE, message, cause);
        }

        @Override
        public void error(String message, Throwable cause, Object... params) {
            logger.log(Level.SEVERE, MessageFormat.format(message, params), cause);
        }

        private Handler buildHandler(AreaType area) {
            FileHandler retVal = null;
            try {
                LoggingConfig loggingConfig = ApplicationContext.getLoggingConfig();
                String fileNamePattern = MessageFormat.format(loggingConfig.getFileNamePattern(), area.name().toLowerCase());
                retVal = new FileHandler(loggingConfig.getDirectory() + "/" + fileNamePattern, loggingConfig.getFileMaxSize(), loggingConfig.getFilesCount());
                retVal.setFormatter(new Formatter() {
                    @Override
                    public String format(LogRecord record) {
                        StringBuffer retVal = new StringBuffer(MessageFormat.format(
                                LOG_RECORD_FORMAT,
                                record.getMillis(),
                                record.getLevel().getName(),
                                record.getThreadID(),
                                record.getMessage()
                        ));

                        Throwable thrown = record.getThrown();
                        if (thrown != null) {
                            StringWriter stringWriter = new StringWriter();
                            thrown.printStackTrace(new PrintWriter(stringWriter));
                            retVal.append(stringWriter.getBuffer());
                        }

                        return retVal.toString();
                    }
                });
            } catch (IOException e) {
                java.util.logging.Logger.getLogger("").log(Level.SEVERE, "Error building TMS application logger.", e);
            }
            return retVal;
        }
    }

}
